package com.jyh.filter;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.jyh.util.Utils;

/**
 * 使用注解标注过滤器
 * 
 * @WebFilter将一个实现了javax.servlet.Filter接口的类定义为过滤器 属性filterName声明过滤器的名称,可选
 *                                                属性urlPatterns指定要过滤
 *                                                的URL模式,也可使用属性value来声明.(
 *                                                指定要过滤的URL模式是必选属性)
 * 
 */
@WebFilter(filterName = "myFilter", urlPatterns = "/*", asyncSupported = true)
public class MyFilter implements Filter {
	protected final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Override
	public void destroy() {
		System.out.println("过滤器销毁");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request2 = (HttpServletRequest) request;
		String ip = getIpAddress(request2);
		logger.info("请求者IP：{}：请求资源：{}，params:{}", ip, request2.getRequestURI(),
				JSONObject.toJSONString(request2.getParameterMap()));

		// 不过滤的uri
		String[] notFilter = new String[] { "login","js","gif","jpg","bmp","png","css","ico"};
		// 请求的uri
		String uri = ((HttpServletRequest) request).getRequestURI();

		// 是否过滤
		boolean doFilter = true;
		for (String s : notFilter) {
			if (uri.indexOf(s) != -1) {
				// 如果uri中包含不过滤的uri，则不进行过滤
				doFilter = false;
				break;
			}
		}
		if (doFilter) {
			// 执行过滤
			// 从session中获取登录者实体
			Object obj = ((HttpServletRequest) request).getSession().getAttribute("username");
			if (null == obj || "".equals(obj) || "null".equals(obj)) {
				// 如果session中不存在登录者实体，则弹出框提示重新登录
				// 设置request和response的字符集，防止乱码

				PrintWriter out = response.getWriter();
				String loginPage = "/loan/login";
				StringBuilder builder = new StringBuilder();
				builder.append("<script type=\"text/javascript\">");
				builder.append("alert('" + Utils.chinaToUnicode("网页过期，请重新登录!") + "');");
				builder.append("window.top.location.href='");
				builder.append(loginPage);
				builder.append("';");
				builder.append("</script>");
				out.print(builder.toString());
			} else {
				// 如果session中存在登录者实体，则继续
				chain.doFilter(request, response);
			}
		} else {
			// 如果不执行过滤，则继续
			chain.doFilter(request, response);
		}
//		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		System.out.println("过滤器初始化");
	}

	public String getIpAddress(HttpServletRequest request) {
		String ip = null;
		ip = request.getHeader("x-forwarded-for");
		// logger.info("x-forwarded-for:" + ip);
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("X-Forwarded-For");
			// logger.info("request.getHeader(\"X-Forwarded-For\")=" + ip);
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
			// logger.info("request.getHeader(\"Proxy-Client-IP\")=" + ip);
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
			// logger.info("request.getHeader(\"WL-Proxy-Client-IP\")=" + ip);
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
			// logger.info("request.getHeader(\"HTTP_CLIENT_IP\")=" + ip);
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
			// logger.info("request.getHeader(\"HTTP_X_FORWARDED_FOR\")=" + ip);
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
			// logger.info("request.getRemoteAddr()=" + ip);
		}
		if (null != ip && ip.indexOf(',') != -1) {
			// 如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串 IP 值
			// 取X-Forwarded-For中第一个非unknown的有效IP字符串
			// 如：X-Forwarded-For：192.168.1.110, 192.168.1.120, 192.168.1.130,
			// 192.168.1.100
			// 用户真实IP为： 192.168.1.110
			// 注意:当访问地址为 localhost 时 地址格式为 0:0:0:0:0:0:1
			// logger.info("ip=" + ip);
			String[] ips = ip.split(",");
			for (int i = 0; i < ips.length; i++) {
				if (null != ips[i] && !"unknown".equalsIgnoreCase(ips[i])) {
					ip = ips[i];
					break;
				}
			}
			if ("0:0:0:0:0:0:1".equals(ip)) {
				logger.info("由于客户端访问地址使用 localhost，获取客户端真实IP地址错误，请使用IP方式访问");
			}
		}
		if ("unknown".equalsIgnoreCase(ip)) {
			logger.info("由于客户端通过Squid反向代理软件访问，获取客户端真实IP地址错误，请更改squid.conf配置文件forwarded_for项默认是为on解决");
		}
		return ip;
	}

}
